/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023.
 * Description: function for setting nfs debug info
 * Author: Pang LiYuan
 * Create: 2023-09-15
 */
#include <linux/seq_file.h>
#include <linux/module.h>
#include <linux/sunrpc/stats.h>
#include <net/net_namespace.h>

#include "nfsd.h"

static void rtos_clear_svc_stat(struct svc_stat *statp)
{
	struct svc_program *prog = statp->program;
	const struct svc_procedure *proc;
	struct svc_version *vers;
	unsigned int i, j;

	for (i = 0; i < prog->pg_nvers; i++) {
		vers = (struct svc_version *)prog->pg_vers[i];
		if (!vers)
			continue;

		proc = vers->vs_proc;
		if (!proc)
			continue;

		for (j = 0; j < vers->vs_nproc; j++, proc++)
			if (proc->pc_debuginfo)
				proc->pc_debuginfo->pc_cnt = 0;
	}
}

ssize_t rtos_nfsd_proc_write_svc_throttle(struct file *file,
		const char __user *buf, size_t count, loff_t *offs)
{
	struct net *net = PDE_DATA(file_inode(file));
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
	unsigned long val;
	int ret;

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	ret = kstrtoul_from_user(buf, count, 0, &val);
	if (ret < 0)
		return ret;

	nfsd_set_rpc_srv_throttle(val);
	rtos_clear_svc_stat(&nn->nfsd_svcstats);

	return count;
}
